//
//  common.h
//  myvpn
//
//  Created by Zhuobin He on 12-12-31.
//  Copyright (c) 2012年 Zhuobin He. All rights reserved.
//


#ifndef myvpn_common_h
#define myvpn_common_h

#include "SysLib.h"


#define max(a, b) ((a)>(b)?(a):(b))
#define min(a, b) ((a)<(b)?(a):(b))
#define WHITESPACE " \t\r\n"


void zmalloc(void *dst, size_t size);


char * trim(char *str);

bool check_str(const char *str);

int execute_cmd(const char *cmd, char *result, int limit);

struct _Route {
    char *address;
    int prefix;
};
typedef struct _Route Route;
typedef Route * PRoute;

void route_delete(PRoute route);

struct _UserInfo {
    char *username;
    char *password;

    char *script;
};
typedef struct _UserInfo UserInfo;
typedef UserInfo * PUserInfo;


void user_info_delete(PUserInfo user);

struct _Thread {
    void *ret;
    bool running;
#ifndef OS_WIN
    pthread_t thread;
#endif
};
typedef struct _Thread Thread;
typedef Thread * PThread;

struct _ThreadLock {
#ifndef OS_WIN
    pthread_mutex_t mut;
#endif
};
typedef struct _ThreadLock ThreadLock;
typedef ThreadLock * PThreadLock;

struct _VpnConfig {
    // share config
    int mode;
    PUserInfo *users;
    char *dev;
    char *network;
    char *host;
    int port;
    char *log_file;
    int log_level;
    int read_buffer_size;
    int write_buffer_size;

    int renew_interval;

    int route_conf_ver;
    PRoute *routes;

    char *tcp_ports;
    char *udp_ports;

    char *route_cache_file;
    char *state_file;
};

typedef struct _VpnConfig VpnConfig;
typedef VpnConfig * PVpnConfig;

void vpn_config_delete(PVpnConfig conf);
bool vpn_config_verify(PVpnConfig conf);


struct _Buffer {
    char *buf;
    int from;
    int to;
    int capacity;
};
typedef struct _Buffer Buffer;
typedef Buffer * PBuffer;



PBuffer buffer_new(int size);
void buffer_delete(PBuffer buf);

char * buffer_pread(PBuffer buf);
char * buffer_pwrite(PBuffer buf);
void buffer_pread_inc(PBuffer buf, int len);
void buffer_pwrite_inc(PBuffer buf, int len);
int buffer_readable(PBuffer buf);
int buffer_writable(PBuffer buf);

void buffer_copy(PBuffer dst, PBuffer src);

void buffer_compact(PBuffer buf);
bool buffer_ends_with(PBuffer buf, const char * str);

void buffer_clear(PBuffer buf);


void set_log_level(int level);
void set_log_file(const char *log_file);

extern int _log_level;

bool is_log_debug();

void log_error(const char *msg, ...);
void log_info(const char *msg, ...);
#ifdef LOG_DEBUG_ENABLE
void log_debug(const char *msg, ...);
void log_trace(const char *msg, ...);
#else
#define log_trace(msg, ...)
#define log_debug(msg, ...)
#endif


char * string_alloc(const char *str);
int str2int(const char *str);

PThread thread_start(void *(*target)(void *), void *arg);
void thread_delete(PThread thread);

PThreadLock threadlock_new();
void threadlock_delete(PThreadLock lock);
bool threadlock_acquire(PThreadLock lock);
bool threadlock_release(PThreadLock lock);


struct _BitSet {
    unsigned char *bits;
    int size;
};

typedef struct _BitSet BitSet;
typedef BitSet * PBitSet;

PBitSet bitset_new(int size);
bool bitset_check(PBitSet bits, int index);
void bitset_set(PBitSet bits, int index, bool is_set);
void bitset_delete(PBitSet bits);


void ip_str_to_num(char *str, int limit, unsigned char *dst);

#endif
